#include "i2c_dev.h"
#include <cstdio>
#include <cstdlib>
#include <cstring>
extern "C" {
    #include <unistd.h>
    #include <fcntl.h>
    #include <sys/types.h>
    #include <sys/ioctl.h>
    #include <linux/types.h>
    #include <linux/i2c.h>
    #include <linux/i2c-dev.h>
}
#include <QMessageBox>

using namespace std;

i2c_dev::i2c_dev(QObject *parent,char *filename,unsigned char dev_addr) : QObject(parent)
{
    this->filename = filename;
    this->dev_addr = dev_addr;
    this->fd = open(filename,O_RDWR);
    if(this->fd < 0)
    {
        QString digTitle = "information消息框";
        QString strInfo = "I2C_RDWR err";
        QMessageBox::information(nullptr,digTitle,strInfo,QMessageBox::Ok,QMessageBox::NoButton);
        this->is_open_dev = false;
    }
    else
    {
        printf("open file %s\n",filename);
        this->is_open_dev = true;
    }
}

i2c_dev::~i2c_dev()
{
    if(this->is_open_dev)
    {
        close(this->fd);
        printf("close %s\n",this->filename);
    }
}

/**
 * @description:i2c发送数据函数
 * param - buf:发送的数据
 * param - len:数据长度
 * @return: 操作结果
*/
int i2c_dev::i2c_write(unsigned char reg_addr, unsigned char *buf,unsigned char len)
{
    unsigned char *msg_buf = new unsigned char[len+1];
    struct i2c_rdwr_ioctl_data data;
    struct i2c_msg messages;

    msg_buf[0] = reg_addr;
    memcpy(&msg_buf[1],buf,len);
    messages.addr = this->dev_addr;
    messages.flags = 0;
    messages.len = len+1;
    messages.buf = msg_buf;
    data.msgs = &messages;
    data.nmsgs = 1;
    if(ioctl(this->fd,I2C_RDWR,&data) < 0)
    {
        printf("I2C_RDWR err\n");
        return -1;
    }
    usleep(50);
    delete [] msg_buf;

    return 0;
}

/**
 * @description:i2c读取数据函数
 * param - buf:数据缓冲区
 * param - len:读取的数据长度
 * @return: 操作结果
*/
int i2c_dev::i2c_read(unsigned char reg_addr, unsigned char *buf, unsigned char len)
{
    struct i2c_rdwr_ioctl_data data;
    struct i2c_msg messages[2];

    messages[0].addr = this->dev_addr;
    messages[0].flags = 0;
    messages[0].len = 1;
    messages[0].buf = &reg_addr;
    messages[1].addr = this->dev_addr;
    messages[1].flags = I2C_M_RD;
    messages[1].len = len;
    messages[1].buf = buf;
    data.msgs = messages;
    data.nmsgs = 2;
    if(ioctl(this->fd,I2C_RDWR,&data) < 0)
    {
        printf("I2C_RDWR err\n");
        return -1;
    }
    usleep(50);

    return 0;
}
